﻿using log4net;
using log4net.Config;
using log4net.Repository;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QiAdmin.Core.Services.Log;

namespace QiAdmin.Core.Services.Log.Log4Net
{
    public class Log4NetService : ILogService
    {
        readonly string RepositoryName = "QiAdminRepository";
        readonly string ConfigPath = AppDomain.CurrentDomain.BaseDirectory + "Services/Log/Log4Net/log4net.config";
        readonly ConcurrentDictionary<string, ILog> Loggers = new ConcurrentDictionary<string, ILog>();
        public Log4NetService()
        {
            if (!File.Exists(ConfigPath))
            {
                throw new SystemException("未找到log4net配置文件:" + ConfigPath);
            }
            ILoggerRepository loggerRepository = LogManager.CreateRepository(RepositoryName);
            XmlConfigurator.ConfigureAndWatch(loggerRepository, new FileInfo(ConfigPath));
        }


        /// <summary>
        /// 获取记录器
        /// </summary>
        /// <param name="source">soruce</param>
        /// <returns></returns>
        private ILog GetLogger(string source)
        {
            if (Loggers.ContainsKey(source))
            {
                return Loggers[source];
            }
            else
            {
                ILog logger = LogManager.GetLogger(RepositoryName, source);
                Loggers.TryAdd(source, logger);
                return logger;
            }
        }

        /// <summary>
        /// 获取日志详情
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private string GetLogMsg(string msg)
        {
            StackTrace stackTrace = new StackTrace();
            StackFrame stackFrame = stackTrace.GetFrame(2);
            string message = $"\r\n【Action】{stackFrame.GetMethod().Name}\r\n【Detail】{msg}";
            return message;
        }


        public void Debug(string msg, Exception exception = null)
        {
            ILog logger = GetLogger("Debug");
            if (logger.IsDebugEnabled)
            {
                string message = GetLogMsg(msg);
                logger.Debug(exception == null ? message : $"{message}\r\n【Exception】", exception);
            }
        }

        public void Error(string msg, Exception exception = null)
        {
            ILog logger = GetLogger("Error");
            if (logger.IsErrorEnabled)
            {
                string message = GetLogMsg(msg);
                logger.Error(exception == null ? message : $"{message}\r\n【Exception】", exception);
            }
        }

        public void Info(string msg, Exception exception = null)
        {
            ILog logger = GetLogger("Info");
            if (logger.IsInfoEnabled)
            {
                string message = GetLogMsg(msg);
                logger.Info(exception == null ? message : $"{message}\r\n【Exception】", exception);
            }
        }

        public void Warn(string msg, Exception exception = null)
        {
            ILog logger = GetLogger("Warn");
            if (logger.IsWarnEnabled)
            {
                string message = GetLogMsg(msg);
                logger.Warn(exception == null ? message : $"{message}\r\n【Exception】", exception);
            }
        }

        public void Fatal(string msg, Exception exception = null)
        {
            ILog logger = GetLogger("Fatal");
            if (logger.IsFatalEnabled)
            {
                string message = GetLogMsg(msg);
                logger.Fatal(exception == null ? message : $"{message}\r\n【Exception】", exception);
            }
        }
    }
}
